package jsu.lipengcheng.trafficnet.service.Impl;

import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.rabbitmq.client.Channel;
import jsu.lipengcheng.trafficnet.Util.RideslockUtil;
import jsu.lipengcheng.trafficnet.common.BeanThread;
import jsu.lipengcheng.trafficnet.common.PageResult;
import jsu.lipengcheng.trafficnet.handler.BenEX;
import jsu.lipengcheng.trafficnet.mapper.ActivityMapper;
import jsu.lipengcheng.trafficnet.mapper.ActivityUserMapper;
import jsu.lipengcheng.trafficnet.pojo.Activity;
import jsu.lipengcheng.trafficnet.pojo.ActivityUser;
import jsu.lipengcheng.trafficnet.service.ActivityService;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.beans.Transient;
import java.io.IOException;
import java.time.Duration;
import java.time.LocalDate;
import java.time.temporal.ChronoUnit;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

@Service
@RabbitListener(queues = "activity-queues")
public class ActivityServiceImpl implements ActivityService {
    @Autowired
    private ActivityMapper activityMapper;
    @Autowired
    private ActivityUserMapper activityUserMapper;
    @Autowired
    private AdminServiceImpl adminServiceImpl;
    @Autowired
    private StringRedisTemplate stringRedisTemplate;
    @Autowired
    private RedissonClient redissonClient;
    @Autowired
    private RabbitTemplate rabbitTemplate;

    @Override
    public Activity selectbyid(int id) {
        Activity activity = activityMapper.selectById(id);
        return activity;
    }

    @Override
    public List<Activity> selectall() {
        List<Activity> activityList= activityMapper.selectList(null);
        return activityList;
    }

    /**
     * 分页查询活动
     * @param page
     * @param pageSize
     * @param start
     * @param end
     * @param score
     * @return
     */
    public PageResult selectbypage(Integer page, Integer pageSize, LocalDate start, LocalDate end, Integer score,String name) {
        PageHelper.startPage(page, pageSize);
        List<Activity> activityList= activityMapper.selectbypage(start,end,score,name);
        Page<Activity> activityPage=(Page<Activity>)activityList;
        PageResult pageResult=new PageResult(activityPage.getTotal(),activityPage.getResult());
        return pageResult;
    }

    @Override
    @Transactional
    public void insert(Activity activity) {
        activity.setStatus(1);
        activityMapper.insert(activity);
        //保存活动到redis中
        // 计算相差多少天
        long days = ChronoUnit.DAYS.between(LocalDate.now(), activity.getEndTime());
        long day = days + 1;
        stringRedisTemplate.opsForValue().set("activity:id:" + activity.getId(),activity.getNum(),day,TimeUnit.DAYS);
    }

    @Override
    public void update(Activity activity) {
        activityMapper.updateById(activity);
    }

    @Override
    public void delete(Integer id) {
        activityMapper.deleteById(id);
    }

    @Override
    public List<Activity> selectbystatus(Integer status) {
       List<Activity> activityList = activityMapper.selectbystatus(status);
        return activityList;
    }
    /**
     * 秒杀用户参加活动
     * @param
     */
    @RabbitHandler
    public void receiveMessage(Message message, ActivityUser activityUser, Channel channel){
        System.out.println("已经收到了消息"+activityUser);
        try {
           adminServiceImpl. extracted(activityUser);
            channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
    private static final DefaultRedisScript<Long> SECKILL_SCRIPT;
    static {
        SECKILL_SCRIPT=new DefaultRedisScript<>();
        SECKILL_SCRIPT.setLocation(new ClassPathResource("seckill.lua"));
        SECKILL_SCRIPT.setResultType(Long.class);
    }
    public void insertuser(Integer id) {
        Integer userId = BeanThread.get();
        //执行lua脚本
        Long result1 = stringRedisTemplate.execute(
                SECKILL_SCRIPT,
                Collections.emptyList(),
                id.toString(), userId.toString()
        );
        int result = result1.intValue();
        //判断结果是不是为0，不为0代表没有购买资格，为0，有购买资格把下单信息保存到队列里面
        if (result!=0){
            throw new BenEX(result==1 ? "库存不足": "不能重复下单");
        }
        //有资格保存数据到mq消息
        ActivityUser activityUser = new ActivityUser();
        activityUser.setUserId(userId);
        activityUser.setActivityId(id);
        rabbitTemplate.convertAndSend("activity-exchange","join.activity",activityUser);
    }

//    public void insertuser(Integer id) {
//        Integer userid = BeanThread.get();
//        Activity activity = activityMapper.selectById(id);
//        if(Integer.parseInt(activity.getNum())==0){
//            throw new BenEX("人数已满");
//        }
//        //创建锁对象
////        RideslockUtil lock = new RideslockUtil("order:" + userid, redisTemplate);
//        RLock lock = redissonClient.getLock("lock:order:" + userid);
//        //获取锁
//        boolean tylock = lock.tryLock();
//        if (!tylock){
//            throw new BenEX("你已经购买过了！");
//        }
//        try {
//            ActivityService proxy = (ActivityService) AopContext.currentProxy();
//            proxy.creatactivity(id, userid);
//        } finally {
//            lock.unlock();
//        }
//    }

//    @Transactional
//    public  void creatactivity(Integer id, Integer userid) {
//            //一个人只能参加一个活动
//            ActivityUser activityuser = activityUserMapper.selectbyuseridid(userid, id);
//            if (activityuser != null) {
//                throw new BenEX("用户已经参加过了！");
//            }
//            //活动人数减一
//            int i = activityMapper.updatenum(id);
//            if (i == 0) {
//                throw new BenEX("人数已满");
//            }
//            ActivityUser activityUser = new ActivityUser();
//            activityUser.setUserId(userid);
//            activityUser.setActivityId(id);
//            activityUserMapper.insert(activityUser);
//
//    }


    /**
     * 查看用户参加的活动
     * @param userid
     * @return
     */
    public List<Activity> findactivitybyuserid(Integer userid) {
        List<Integer> list= activityUserMapper.selectbyuserid(userid);
        List<Activity> activityList=activityMapper.selectByIds(list);
        return activityList;
    }

    @Override
    public int selectsum() {
      int sum =  activityMapper.selectsum();
        return sum;
    }
}
